package com.gitee.feizns.dynamic.reflect;

import java.lang.annotation.Annotation;
import java.util.Deque;
import java.util.function.Function;

/**
 * 注解工具类
 * @author feizns
 * @since 2023/2/26
 */
public abstract class Annotations {

    /**
     * <b>遍历目标类的整个继承链来查找类上的注解（含接口查找）</b>
     * <p>
     *     假设A类继承了B类、在A上查找注解、找不到则在B上继续找
     * </p>
     * @return {@link Annotation}
     * @param <A> 注解类型
     */
    public static <A extends Annotation> A of(Class<?> type, Class<A> annotationType) {
        return of(type, t -> t.getAnnotation(annotationType));
    }

    /**
     * <b>遍历目标类的整个继承链来查找注解（含接口查找）</b>
     * @return {@link Annotation}
     * @param <A> 注解类型
     */
    public static <A extends Annotation> A of(Class<?> type, Function<Class<?>, A> mapper) {
        Deque<Class<?>> classesOrInterfaces = Classes.ofClassesAndInterfaces(type);
        for (Class<?> classesOrInterface : classesOrInterfaces) {
            A annotation = mapper.apply(classesOrInterface);
            if ( annotation != null )
                return annotation;
        }
        return null;
    }

}
